package com.webinsky.web.utils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.codec.multipart.FilePart;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import com.webinsky.domain.resource.ResType;

public class FileManager {
//	private String saveImgPath;
//	private String readImgPath;
//	
//	private String saveVideoPath;
//	private String readVideoPath;
	
	private String basePath;
	
	private static Map<String, FileManager> fileManagers = new HashMap<>();
	
	public static FileManager create(String basePath){
		if ( fileManagers.get(basePath) == null ){
			FileManager manager = new FileManager(basePath);
			fileManagers.put(basePath, manager);
		}
		return fileManagers.get(basePath);
	}
	
	private FileManager(String basePath){
		this.basePath = basePath;
	}
	
	private void writeFile(InputStream in, OutputStream out) throws IOException{
		byte[] data = new byte[1024];
		while ( in.read(data) > -1 ){
			out.write(data);
			data = new byte[1024];
		}
	}
	
	/**
	 * 保存excel文件
	 * @param data
	 * @param bookMode
	 * @param fileName
	 * @param lang
	 * @return
	 */
	public Mono<String> saveExcelFile(FilePart filePart, String bookMode, String fileName, String lang){
		if ( filePart != null && bookMode != null && fileName != null && lang != null ){
			try {
				String resPath = basePath + File.separator + bookMode + File.separator + lang + File.separator + "excel";
				Path pResPath = Paths.get(resPath);
				if ( !Files.exists(pResPath) ){
					try {
						Files.createDirectories(pResPath);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				Date now = new Date();
				String filePath = resPath + File.separator + now.getTime() + "_" + fileName;
				Path tempFile = Files.createFile(Paths.get(filePath));
//				Mono<Void> voidReturn = filePart.transferTo(tempFile.toFile());
//				return voidReturn.thenReturn(filePath);
				AsynchronousFileChannel channel =
		                AsynchronousFileChannel.open(tempFile, StandardOpenOption.WRITE);
		        DataBufferUtils.write(filePart.content(), channel, 0)
		                .doOnComplete(() -> {
		                	try {
								channel.close();
							} catch (Exception e) {
								e.printStackTrace();
							}
		                	System.out.println("finish");
		        }).blockLast();
		            
				return Mono.just(filePath);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}
	
	
	/**
	 * 保存資源文件
	 * @param data
	 * @param fileName
	 * @return
	 */
	public Flux<String> saveResFile(Flux<DataBuffer> data, ResType type, String bookMode, String fileName, String lang){
		if ( data != null ){
			return data.bufferUntil(fileData -> fileData.readableByteCount() == 0).flatMap(fileDatas -> {
				String imagePath = type == ResType.Image ? "pic" : "mov";
				String resPath = basePath + File.separator + bookMode + File.separator + lang + File.separator + "material" + File.separator + imagePath;
				Path pResPath = Paths.get(resPath);
				if ( !Files.exists(pResPath) ){
					try {
						Files.createDirectories(pResPath);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				String filePath = resPath + File.separator + fileName;
//				Path pImage = Paths.get(filePath);
//				if ( !Files.exists(pImage) ){
						try ( OutputStream out = new FileOutputStream(new File(filePath)); ){
							fileDatas.forEach(db -> {
								try (InputStream in = db.asInputStream()){
									writeFile(in, out);
								} catch (Exception e) {
									e.printStackTrace();
								}
							});
						} catch (Exception e1) {
							e1.printStackTrace();
						}
//				}
				return Flux.just(fileName);
			});
		}
		return null;
	}
	/**
	 * 讀取資源文件
	 * @param resType
	 * @param relativePath
	 * @return
	 */
	public File readResFile(ResType resType, String bookMode, String fileName, String lang){
		String imagePath = resType == ResType.Image ? "pic" : "mov";
		String filePath = basePath + File.separator + bookMode + File.separator + lang + File.separator + "material" + File.separator + imagePath + File.separator + fileName;
		Path path = Paths.get(filePath);
        return path.toFile();
	}
	
	
//	public static void main(String[] args) {
//		LocalDate localDate = LocalDate.now();
//		System.out.println(localDate.toString());
//	}
}
